/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.prueba.controlador;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.prueba.modelo.anotacion.ASArchivo;

/**
 *
 * @author 43579648
 */
public abstract class ControladorAbstracto<T> {
    private Class<T> entityClass;
    private T entity;

    public ControladorAbstracto(Class<T> entityClass) {
            this.entityClass = entityClass;
    }

    protected abstract Connection obtenerConexion();
    
    
    protected void ejecutarActualizacion(String sql) throws SQLException{
        Statement st = null;
        try {
            System.out.println("Ejecutando SQL : " + sql);
            st = obtenerConexion().createStatement();
            st.execute(sql);
        } catch (SQLException ex) {
            throw ex;
        }finally{
            if(st!=null)
                st.close();
                obtenerConexion().close();
        }
    }
    
    protected ResultSet obtenerDatos(String sql) throws SQLException{
        Statement st = null;
        ResultSet rs = null;
        try {
            st = obtenerConexion().createStatement();
            rs = st.executeQuery(sql);
            return rs;
        } catch (SQLException ex) {
            throw ex;
        }finally{
            if(st!=null)
                st.close();
                obtenerConexion().close();
        }
    }
    
    
    protected String obtenerCampos(){
        StringBuffer str = new StringBuffer();
        for(Field f : entityClass.getDeclaredFields()){
            str.append(f.getName()).append(",");
        }
        
        return str.toString().substring(0,str.toString().length()-1);
    }
    
    protected String obtenerValoresCampos() throws Exception{
        StringBuffer str = new StringBuffer();
        try{
        for(Method m : entityClass.getMethods()){
            if(m.getName().contains("get"))
                str.append(m.invoke(new Object(), new Object())).append(",");
        }
        return str.toString().substring(0,str.toString().length()-1);
        }catch(Exception e){
            e.printStackTrace();
            throw e;
        }
    }
    
    private String obtenerValoresCamposIndividuales() throws Exception{
        StringBuffer str = new StringBuffer();
        try{
        for(Method m : entityClass.getMethods()){
            if(m.getName().contains("get"))
                str.append(m.getName().replace("get", "")).append(" = ").append(m.invoke(new Object(), new Object()));
        }
        return str.toString().substring(0,str.toString().length()-1);
        }catch(Exception e){
            e.printStackTrace();
            throw e;
        }
    }
    
    protected String obtenerLibreria(){
        for(Annotation a : entityClass.getAnnotations()){
            if(a.annotationType().getName().equals("ASArchivo"))
                return ((ASArchivo)a).libreria();
        }
        return "";
    }
    
    protected String obtenerNombreArchivo(){
        for(Annotation a : entityClass.getAnnotations()){
            if(a.annotationType().getName().equals("ASArchivo"))
                return ((ASArchivo)a).nombre();
        }
        return "";
    }
    
    

    
    /*public void modificar() throws Exception {
        try{
            StringBuffer sql = new StringBuffer();
            sql.append("update ");
            sql.append(obtenerLibreria());
            sql.append(".");
            sql.append(obtenerNombreArchivo());
            sql.append(" set ");
            sql.append(obtenerValoresCamposIndividuales());
            sql.append(" where ");
            sql.append("  ");
            
        }catch(Exception e){
            e.printStackTrace();
            getEntityManager().getTransaction().rollback();
            throw new Exception(e);
        }
    }

    public void eliminar() throws Exception {
        try{
            getEntityManager().getTransaction().begin();
            getEntityManager().remove(getEntityManager().merge(entity));
            getEntityManager().getTransaction().commit();
        }catch(Exception e){
            e.printStackTrace();
            getEntityManager().getTransaction().rollback();
            throw new Exception(e);
        }
    }

    public void crear(T entity) throws Exception {
        try{
            getEntityManager().getTransaction().begin();
            getEntityManager().persist(entity);
            getEntityManager().getTransaction().commit();
        }catch(Exception e){
            e.printStackTrace();
            getEntityManager().getTransaction().rollback();
            throw new Exception(e);
        }
    }

    public void modificar(T entity) throws Exception {
        try{
            getEntityManager().getTransaction().begin();
            getEntityManager().merge(entity);
            getEntityManager().getTransaction().commit();
            getEntityManager().flush();
        }catch(Exception e){
            e.printStackTrace();
            getEntityManager().getTransaction().rollback();
            throw new Exception(e);
        }
    }

    public void eliminar(T entity) throws Exception {
        try{
            getEntityManager().getTransaction().begin();
            getEntityManager().remove(getEntityManager().merge(entity));
            getEntityManager().getTransaction().commit();
        }catch(Exception e){
            e.printStackTrace();
            getEntityManager().getTransaction().rollback();
            throw new Exception(e);
        }
    }

    public T encontrar(Object id) {
        
        return getEntityManager().find(entityClass, id);
    }

    public List<T> obtenerTodos() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        List<T> list = getEntityManager().createQuery(cq).getResultList();
        for(T t : list){
            getEntityManager().refresh(t);
        }
        return list;
    }
    
    
    public List<T> obtenerTodosDistintos() {
        Query q = getEntityManager().createQuery("Select distinct o from " + entityClass.getSimpleName() + " o");
        return q.getResultList();
    }

    public List<T> encontrarPorRango(int[] range) {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        q.setMaxResults(range[1] - range[0]);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }

    public int obtenerContadorTodos() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
        cq.select(getEntityManager().getCriteriaBuilder().count(rt));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        return ((Long) q.getSingleResult()).intValue();
    }

    public T getEntity() {
        return entity;
    }

    public void setEntity(T entity) {
        this.entity = entity;
    }
    
    */
}
